package com.yishun.springboot.service;

import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import com.RequestGongWuShu.vehicle;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.yinquan.util.ResultUtils;
import com.yishun.springboot.mapper.GwsVehicleMasterDetailedMapper;
import com.yishun.springboot.mapper.PinyiVehicleDetailedMapper;
import com.yishun.springboot.mapper.WeiZhongYunVehicleDetailedToPinyiGetDataMapper;
import com.yishun.springboot.pojo.GwsVehicleDTO;
import com.yishun.springboot.pojo.GwsVehicleMasterDetailed;
import com.yishun.springboot.pojo.PinyiVehicleDetailed;

import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * 定时上传车辆道闸心跳包
 *
 * @author XiaoHuang
 * @date 2021年3月24日上午11:48:53
 */
@Slf4j
@Service
@Component
public class GongWuSuTimedUploadVehicleHeartBeatService {

    @Autowired
    PinyiVehicleDetailedMapper pinyiVehicleDetailedMapper;

    @Autowired
    GwsVehicleMasterDetailedMapper gwsVehicleMasterDetailedMapper;

    @Autowired
    WeiZhongYunVehicleDetailedToPinyiGetDataMapper weiZhongYunVehicleDetailedToPinyiGetDataMapper;

    String api_version = "1.0";
    String baseUlr = "http://szwb.sz.gov.cn:2018/openapi";// 请求地址

    @Async(value = "asyncExecutor")
    @Scheduled(fixedRate = 1000 * 30)
    public void timingUpdateLocalData() {
        log.info("------------定时上传车辆道闸心跳包------------开始。");
        // 成员方法变量声明
        /**
         * 入参项目请求参数 (请求大循环赋参)
         */
        List<GwsVehicleMasterDetailed> gwsVehicleMasterDetailedList = null;

        /**
         * 入参道闸参数 （请求小循环赋参）因为一个项目有一个以上道闸设备，一对多关系
         */
        List<PinyiVehicleDetailed> pinyiVehicleList = null;
        List<PinyiVehicleDetailed> howmanyVehicleDetailed = null;

        String currApiKey = "初始赋值api_key";
        String currEngCode = "初始赋值Eng_code";
        String currProjectCode = "初始赋值Project_code";
        String currApiVersion = "初始赋值Api_version";

        String currDeviceNo = "初始赋值currDeviceNo";
        String beatTime = "初始赋值beatTime";

        JSONObject body = new JSONObject();
        JSONObject param = new JSONObject();

        // 实例实际请求方法以及设置请求参数
        vehicle v = new vehicle();
        // 入参项目请求参数
        DateUtil dateUtil = new DateUtil();

        gwsVehicleMasterDetailedList = gwsVehicleMasterDetailedMapper.findAll();
        pinyiVehicleList = pinyiVehicleDetailedMapper.findAll();

        for (int i = 0; i < gwsVehicleMasterDetailedList.size(); i++) {

            currApiKey = gwsVehicleMasterDetailedList.get(i).getApi_key();
            currEngCode = gwsVehicleMasterDetailedList.get(i).getEng_code();
            currProjectCode = gwsVehicleMasterDetailedList.get(i).getProject_code();
            currApiVersion = gwsVehicleMasterDetailedList.get(i).getApi_version();
            // 入参项目请求参数
            v.setApi_key(currApiKey);
            v.setEngCode(currEngCode);
            v.setProjectCode(currProjectCode);
            v.setApi_version(currApiVersion);

            // 查询一个项目对应几个道闸
            howmanyVehicleDetailed = pinyiVehicleDetailedMapper
                    .selectOneProjectHowManyByGwsProjectCode(gwsVehicleMasterDetailedList.get(i).getProject_code());
            // 入参道闸参数
            for (int j = 0; j < howmanyVehicleDetailed.size(); j++) {
                // 根据项目号查询道闸设备信息
                v.setBaseUlr(baseUlr);

                String timestamp = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");

                param.put("api_key", currApiKey);
                param.put("project_code", currProjectCode);
                param.put("eng_code", currEngCode);
                param.put("api_version", currApiVersion);
                param.put("timestamp", timestamp);


                // 换成假数据，后续可以if是十五高的项目就换
                currDeviceNo = howmanyVehicleDetailed.get(j).getDeviceNo();
//			log.info("当前第 "+j+" 个道闸设备号："+currDeviceNo);
//			
                if (howmanyVehicleDetailed.get(j).getGwsProjectCode().equals("XM20190707"))
                    currDeviceNo = (weiZhongYunVehicleDetailedToPinyiGetDataMapper.selectByDeviceNumber(currDeviceNo))
                            .getDeviceNumber();

                body.put("device_no", currDeviceNo); // attention 需要对应已经存在的
                body.put("beat_time", dateUtil.now());

                param.put("body", body);// body


                try {
                    v.heartbeat(param, body);
                } catch (Exception e) {
                    e.printStackTrace();
                }

            } // for---end
        }
    }

    public String uploadVehicleDetailed(GwsVehicleDTO vehicleDTO) {
        JSONObject body = new JSONObject();
        JSONObject param = new JSONObject();

        String projectCode = vehicleDTO.getProjectCode();

        GwsVehicleMasterDetailed detailed = gwsVehicleMasterDetailedMapper.selectOneByGwsProjectCode(projectCode);

        if (detailed == null) {
            JSONObject.toJSONString(ResultUtils.jsonFail("未在gws_vehicle_masterdetailed表添加信息"),
                    SerializerFeature.WriteMapNullValue);
        }

        // 头部入参
        param.put("api_key", detailed.getApi_key());
        param.put("project_code", projectCode);
        param.put("eng_code", detailed.getEng_code());
        param.put("api_version", "1.0");
        param.put("timestamp", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));

        // body入参
        body.put("device_no", vehicleDTO.getDeviceNo());
        body.put("name", vehicleDTO.getName());
        body.put("region_no", vehicleDTO.getRegionNo());
        body.put("region_type", vehicleDTO.getRegionType());

        // 不是必传
//		body.put("region_name", vehicleDTO.getRegionName());
//		body.put("install_company", vehicleDTO.getInstallCompany());
//		body.put("device_installation_date", vehicleDTO.getDeviceInstallationDate());

        vehicle v = new vehicle();

        String resStr = v.addBasicInfo(param, body);

        JSONObject resJsonObject = JSONObject.parseObject(resStr);

        if (!resJsonObject.getString("code").equals("0")) {
            return JSONObject.toJSONString(ResultUtils.jsonFail("上传车辆基本信息失败"), SerializerFeature.WriteMapNullValue);
        }

        int res2 = pinyiVehicleDetailedMapper.add(vehicleDTO);

        if (res2 < 1) {
            JSONObject.toJSONString(ResultUtils.jsonFail("数据库新增失败"), SerializerFeature.WriteMapNullValue);
        }

        return JSONObject.toJSONString(ResultUtils.jsonSuccess(), SerializerFeature.WriteMapNullValue);
    }

    /**
     * 获取签名
     *
     * @param: [apiKey, apiVersion, engCode, projectCode, timestamp, body]
     * @return: java.lang.String
     */
    public static String getSignature(String apiKey, String apiVersion, String engCode, String projectCode,
                                      String timestamp, String body) {
        String str4MD5 = String.format("api_key%sapi_version%sbody%seng_code=%sproject_code=%stimestamp%s", apiKey,
                apiVersion, body.isEmpty() ? "{}" : body, engCode, projectCode, timestamp);
        return getMD5Code(str4MD5);
    }

    public static String getMD5Code(String strObj) {
        String resultString = null;
        try {
            resultString = new String(strObj);
            MessageDigest md = MessageDigest.getInstance("MD5");
            Charset charset = Charset.forName("UTF-8");
            resultString = byteToString(md.digest(strObj.getBytes(charset)));
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        }
        return resultString;
    }

    // 转换字节数组为16进制字串
    private static String byteToString(byte[] bByte) {
        StringBuffer sBuffer = new StringBuffer();
        for (int i = 0; i < bByte.length; i++) {
            sBuffer.append(byteToArrayString(bByte[i]));
        }
        return sBuffer.toString();
    }

    private static String byteToArrayString(byte bByte) {
        int iRet = bByte;
        if (iRet < 0) {
            iRet += 256;
        }
        int iD1 = iRet / 16;
        int iD2 = iRet % 16;
        return strDigits[iD1] + strDigits[iD2];
    }

    // 全局数组
    private final static String[] strDigits = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D",
            "E", "F"};

}
